<template>
  <div class="Country-container">
    <div class="tree-wrap">
      <v-skeleton-loader
        v-if="loading"
        height="100%"
        type="list-item@20"
      ></v-skeleton-loader>
      <Tree
        v-else
        :items="treeItems"
        @add="openAddCountry"
        addTooltip="Add Country"
        hoverable
        expand-icon="mdi-chevron-down"
      >
        <template #title>
          <span class="ml-4"> Country > City > Region > Area </span>
        </template>
        <template #label="{ item }">
          <div>{{ item.name }} ({{ item.shortName }})</div>
        </template>
        <template #append="{ item }">
          <div @click.stop class="action">
            <v-tooltip bottom>
              <template v-slot:activator="{ on, attrs }">
                <v-icon
                  v-if="item.type !== 'Area'"
                  @click="openAddEdit(item, 'add')"
                  v-bind="attrs"
                  v-on="on"
                  small
                  class="mr-2 pointer"
                >
                  mdi-plus-box
                </v-icon>
              </template>
              <span>Add {{ country[country.indexOf(item.type) + 1] }}</span>
            </v-tooltip>
            <v-tooltip bottom>
              <template v-slot:activator="{ on, attrs }">
                <v-icon
                  @click="openAddEdit(item, 'edit')"
                  v-bind="attrs"
                  v-on="on"
                  small
                  class="mr-2 pointer"
                >
                  mdi-square-edit-outline
                </v-icon>
              </template>
              <span>Edit {{ item.type }}</span>
            </v-tooltip>
            <v-tooltip bottom>
              <template v-slot:activator="{ on, attrs }">
                <v-icon
                  small
                  v-bind="attrs"
                  v-on="on"
                  @click="openDelete(item)"
                >
                  mdi-delete
                </v-icon>
              </template>
              <span>Delete {{ item.type }}</span>
            </v-tooltip>
          </div>
        </template>
      </Tree>
    </div>
    <Dialog
      width="480"
      :show-save="step !== 9"
      :title="dialogTitle"
      v-model="showDialog"
      @submit="save"
    >
      <template>
        <AddEditCountry
          ref="addEditCountry"
          v-if="[1, 2].includes(step)"
        ></AddEditCountry>
        <AddEditCity
          ref="addEditCity"
          v-else-if="[3, 4].includes(step)"
        ></AddEditCity>
        <addEditRegion
          ref="addEditRegion"
          v-else-if="[5, 6].includes(step)"
        ></addEditRegion>
        <addEditArea
          ref="addEditArea"
          v-else-if="[7, 8].includes(step)"
        ></addEditArea>
        <DeleteCountry
          :type="selectedType"
          :item="selectedItem"
          v-else-if="step === 9 && selectedItem"
          @delete="deleteCountry"
        ></DeleteCountry>
      </template>
    </Dialog>
  </div>
</template>

<script lang="ts">
import { Vue, Component } from "vue-property-decorator";
import Tree from "@/components/Maintenance/Tree/Tree.vue";
import Dialog from "@/components/Maintenance/Dialog/Dialog.vue";
import AddEditCountry from "@/components/Maintenance/Setting/Country/AddEditCountry.vue";
import AddEditCity from "@/components/Maintenance/Setting/Country/AddEditCity.vue";
import AddEditRegion from "@/components/Maintenance/Setting/Country/AddEditRegion.vue";
import AddEditArea from "@/components/Maintenance/Setting/Country/AddEditArea.vue";
import DeleteCountry from "@/components/Maintenance/Setting/Country/DeleteCountry.vue";
interface ICountry {
  id: string;
  name: string;
  shortName: string;
  type: string;
  children?: ICountry[];
}
@Component({
  components: {
    Tree,
    Dialog,
    AddEditCountry,
    AddEditCity,
    AddEditRegion,
    AddEditArea,
    DeleteCountry,
  },
})
export default class Country extends Vue {
  treeItems: ICountry[] = [];
  country = ["Country", "City", "Region", "Area"];
  getTreeItems() {
    this.loading = true;
    setTimeout(() => {
      this.treeItems = [
        {
          id: "1",
          name: "China",
          shortName: "CN",
          type: "Country",
          children: [
            {
              id: "2",
              name: "Shanghai",
              shortName: "SHA",
              type: "City",
            },
            {
              id: "3",
              name: "Shenzhen",
              shortName: "SZX",
              type: "City",
            },
            {
              id: "5",
              name: "Hong Kong Island",
              shortName: "HK",
              type: "City",
              children: [
                {
                  id: "8",
                  name: "Hong Kong Island",
                  shortName: "HK",
                  type: "Region",
                },
                {
                  id: "6",
                  name: "Kowloon",
                  shortName: "KLN",
                  type: "Region",
                },
                {
                  id: "7",
                  name: "New Territories",
                  shortName: "NT",
                  type: "Region",
                  children: [
                    {
                      id: "18",
                      name: "Islands",
                      shortName: "I",
                      type: "Area",
                    },
                    {
                      id: "19",
                      name: "North",
                      shortName: "N",
                      type: "Area",
                    },
                    {
                      id: "20",
                      name: "Kwai Tsing",
                      shortName: "NTKT",
                      type: "Area",
                    },
                    {
                      id: "21",
                      name: "Sai Kung",
                      shortName: "SK",
                      type: "Area",
                    },
                    {
                      id: "22",
                      name: "Sha Tin",
                      shortName: "ST",
                      type: "Area",
                    },
                  ],
                },
              ],
            },
          ],
        },
      ];
      this.loading = false;
    }, 1500);
  }

  loading = false;

  selectedItem: ICountry | null = null;
  selectedItemParent: ICountry | null = null;
  selectedType = "";

  showDialog = false;
  dialogTitle = "";
  // 1.AddCountry 2.EditCountry 3.AddCity 4.EditCity 5.AddRegion 6.EditRegion 7.AddArea 8.EditArea 9.Delete
  step = -1;

  openDialog() {
    this.showDialog = true;
  }

  closeDialog() {
    this.showDialog = false;
  }
  // Country Dialog
  openAddCountry() {
    this.dialogTitle = "Add Country";
    this.step = 1;
    this.$nextTick(() => {
      const addEditCountryRef = this.$refs.addEditCountry as AddEditCountry;
      addEditCountryRef.resetForm();
    });
    this.openDialog();
  }

  openEditCountry(item: ICountry) {
    this.dialogTitle = "Edit Country";
    this.step = 2;
    this.$nextTick(() => {
      const addEditCountryRef = this.$refs.addEditCountry as AddEditCountry;
      addEditCountryRef.resetForm();
      setTimeout(() => {
        addEditCountryRef.setFormData({
          id: item.id,
          countryShortName: item.shortName,
          countryName: item.name,
        });
      });
    });
  }

  // City Dialog
  openAddCity(item: ICountry) {
    this.step = 3;
    this.dialogTitle = "Add City";
    this.$nextTick(() => {
      const AddEditCityRef = this.$refs.addEditCity as AddEditCity;
      AddEditCityRef.resetForm();
      setTimeout(() => {
        AddEditCityRef.setFormData({
          country: `${item.name} (${item.shortName})`,
        });
      }, 0);
    });
  }

  openEditCity(item: ICountry, parentItem: ICountry) {
    this.step = 4;
    this.dialogTitle = "Edit City";
    this.$nextTick(() => {
      const AddEditCityRef = this.$refs.addEditCity as AddEditCity;
      AddEditCityRef.resetForm();
      setTimeout(() => {
        AddEditCityRef.setFormData({
          id: item.id,
          country: `${parentItem.name} (${parentItem.shortName})`,
          cityShortName: item.shortName,
          cityName: item.name,
        });
      });
    });
  }

  // Region Dialog
  openAddRegion(item: ICountry) {
    this.step = 5;
    this.dialogTitle = "Add Region";
    this.$nextTick(() => {
      const AddEditRegionRef = this.$refs.addEditRegion as AddEditRegion;
      AddEditRegionRef.resetForm();
      setTimeout(() => {
        AddEditRegionRef.setFormData({
          city: `${item.name} (${item.shortName})`,
        });
      });
    });
  }

  openEditRegion(item: ICountry, parentItem: ICountry) {
    this.step = 6;
    this.dialogTitle = "Edit Region";
    this.$nextTick(() => {
      const AddEditRegionRef = this.$refs.addEditRegion as AddEditRegion;
      AddEditRegionRef.resetForm();
      setTimeout(() => {
        console.log(parentItem);
        AddEditRegionRef.setFormData({
          id: item.id,
          city: `${parentItem.name} (${parentItem.shortName})`,
          regionShortName: item.shortName,
          regionName: item.name,
        });
      });
    });
  }

  // Area Dialog
  openAddArea(item: ICountry) {
    this.step = 7;
    this.dialogTitle = "Add Area";
    this.$nextTick(() => {
      const AddEditAreaRef = this.$refs.addEditArea as AddEditArea;
      AddEditAreaRef.resetForm();
      setTimeout(() => {
        AddEditAreaRef.setFormData({
          region: `${item.name} (${item.shortName})`,
        });
      });
    });
  }

  openEditArea(item: ICountry, parentItem: ICountry) {
    this.step = 8;
    this.dialogTitle = "Edit Area";
    this.$nextTick(() => {
      const AddEditAreaRef = this.$refs.addEditArea as AddEditArea;
      setTimeout(() => {
        AddEditAreaRef.setFormData({
          id: item.id,
          region: `${parentItem.name} (${parentItem.shortName})`,
          areaShortName: item.shortName,
          areaName: item.name,
        });
      });
    });
  }

  // action
  openAddEdit(item: ICountry, type: string) {
    this.selectedItem = item;
    if (type === "edit") {
      this.selectedItemParent = this.getParent(
        this.treeItems,
        item.id
      ) as ICountry;
      console.log(this.selectedItemParent, item.id);
    }
    switch (item.type) {
      case "Country":
        if (type === "add") {
          this.openAddCity(item);
        } else if (type === "edit") {
          this.openEditCountry(item);
        }
        break;
      case "City":
        if (type === "add") {
          this.openAddRegion(item);
        } else if (type === "edit") {
          this.openEditCity(item, this.selectedItemParent as ICountry);
        }
        break;
      case "Region":
        if (type === "add") {
          this.openAddArea(item);
        } else if (type === "edit") {
          this.openEditRegion(item, this.selectedItemParent as ICountry);
        }
        break;
      case "Area":
        if (type === "edit") {
          this.openEditArea(item, this.selectedItemParent as ICountry);
        }
        break;
    }
    this.openDialog();
  }

  openDelete(item: ICountry) {
    this.step = 9;
    this.selectedType = item.type;
    this.selectedItem = item;
    switch (item.type) {
      case "Country":
        this.dialogTitle = "Delete  Country";
        break;
      case "City":
        this.dialogTitle = "Delete  City";
        break;
      case "Region":
        this.dialogTitle = "Delete  Region";
        break;
      case "Area":
        this.dialogTitle = "Delete  Area";
        break;
    }
    this.openDialog();
  }

  async save() {
    let selectedItem = this.selectedItem as ICountry;
    let addEditRef = null;
    if (this.step === 1 || this.step === 2) {
      // addCountry and EditCountry
      addEditRef = this.$refs.addEditCountry as AddEditCountry;
    } else if (this.step === 3 || this.step === 4) {
      // addCity and EditCity
      addEditRef = this.$refs.addEditCity as AddEditCity;
    } else if (this.step === 5 || this.step === 6) {
      // addRegion and EditRegion
      addEditRef = this.$refs.addEditRegion as AddEditRegion;
    } else if (this.step === 7 || this.step === 8) {
      // addArea and EditArea
      addEditRef = this.$refs.addEditArea as AddEditArea;
    }
    if (addEditRef) {
      let result = (await addEditRef.validateFormData()) as Record<
        string,
        string
      >;
      if (result) {
        if (this.step === 1) {
          const formData = {
            id: "",
            type: "Country",
            name: result.countryName,
            shortName: result.countryShortName,
          } as ICountry;
          formData.id = String(new Date().getTime());
          this.treeItems.push(formData);
          this.closeDialog();
          return;
        }
        let type = "";
        if ([3, 5, 7].includes(this.step)) {
          type = this.country[this.country.indexOf(selectedItem.type) + 1];
        } else if ([2, 4, 6, 8].includes(this.step)) {
          type = selectedItem.type;
        }
        const nameKey = type.toLowerCase() + "Name";
        const name = result[nameKey];
        const shortNameKey = type.toLowerCase() + "ShortName";
        const shortName = result[shortNameKey];
        const formData = {
          id: "",
          type: type,
          name: name,
          shortName: shortName,
        } as ICountry;
        // Add
        if ([3, 5, 7].includes(this.step)) {
          const selectedItem = this.selectedItem as ICountry;
          if (selectedItem.children) {
            selectedItem.children.push(formData);
          } else {
            this.$set(selectedItem, "children", [formData]);
          }
        }
        // Edit
        if ([2, 4, 6, 8].includes(this.step)) {
          formData.id = result.id as string;
          Object.assign(selectedItem, formData);
        }
        this.closeDialog();
      }
    }
  }

  deleteCountry(item: ICountry) {
    if (item.type === "Country") {
      const index = this.treeItems.indexOf(item);
      this.treeItems.splice(index, 1);
    } else {
      const itemId = item.id;
      const parent = this.getParent(this.treeItems, itemId);
      if (parent) {
        const index = (parent.children as ICountry[]).indexOf(item);
        (parent.children as ICountry[]).splice(index, 1);
      }
    }
    this.closeDialog();
    this.selectedItem = null;
  }

  // 获取父级元素
  getParent(treeItems: ICountry[], childrenId: string): ICountry | undefined {
    for (let i = 0; i < treeItems.length; i++) {
      const treeItem = treeItems[i];
      if (treeItem.children && treeItem.children.length !== 0) {
        if (
          treeItem.children.some((child) => {
            return child.id === childrenId;
          })
        ) {
          return treeItem;
        } else {
          const parent = this.getParent(treeItem.children, childrenId);
          if (parent) {
            return parent;
          }
        }
      }
    }
    return undefined;
  }

  created() {
    this.getTreeItems();
  }

  mounted() {
    this.$store.commit("MaintenanceStore/switchActionIcon", "mdi-file-export");
  }
}
</script>

<style lang="scss" scoped>
@import "./Country.scss";
</style>
